<template>
    <div
        class="page_root"
        :key="queryUpdateFlag"
        data-page-name="平台项目v2-首页"
        data-page-identification="g_7g0hxvd38g"
    >
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
            <!--          选择产品类型-->
            <a-modal
                v-model:visible="state.selectProjectTypeVisible"
                title="新建（请选择产品类型）"
                centered
                width="350px"
                :keyboard="false"
                :mask-closable="false"
                @ok="handleConfirmSelectType"
            >
                <a-radio-group v-model:value="state.selectProjectTypeRadioValue">
                    <a-radio value="迭代产品">迭代产品</a-radio>
                    <a-radio value="产品">产品</a-radio>
                </a-radio-group>
            </a-modal>
            <!--          选择产品类型-->
            <!--          删除项目-->
            <a-modal
                v-model:visible="state.deleteVisible"
                centered
                :ok-button-props="{ loading: state.deleteLoading }"
                :mask-closable="false"
                :keyboard="false"
                @ok="handleSubmitDelete"
            >
                是否确认删除项目？
            </a-modal>
            <!--          删除项目-->
            <!--          新建模板项目-->
            <a-modal
                :title="tgNoSt.title"
                :visible="tgNoSt.visible"
                @ok="submitTgNoProject"
                width="1000px"
                :body-style="{ maxHeight: '800px', overflowY: 'auto' }"
                @cancel="tgNoStCancel"
                ok-text="提交"
                :maskClosable="false"
                destroy-on-close
                centered
                :ok-button-props="{ loading: tgNoSt.okDisabled }"
            >
                <a-form :model="tgNoSt.form" ref="tgNoStRef">
                    <div class="tg-no-st">
                        <div class="pj-title">
                            <div class="pj-title-son">基本信息</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目模板"
                                    name="projectTemplate"
                                    :rules="[{ required: true, message: '请选择项目模板', trigger: 'blur' }]"
                                >
                                    <a-select
                                        :disabled="tgNoSt.isEdit || tgNoSt.isCopy"
                                        :options="tgNoSt.projectTemplateList"
                                        :field-names="{ label: 'templateName', value: 'templateCode' }"
                                        @focus="getTemplate"
                                        :placeholder="selectHolder"
                                        :filter-option="
                                            (input, option) => {
                                                return (
                                                    option.templateName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                )
                                            }
                                        "
                                        v-model:value="tgNoSt.form.projectTemplate"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="项目名称"
                                    name="projectName"
                                    :rules="{ required: true, message: '请输入工厂名称', trigger: 'blur' }"
                                >
                                    <a-input v-model:value="tgNoSt.form.projectName" />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目关联菜单"
                                    name="parentId"
                                    :rules="{ required: true, message: '请选择项目关联菜单', trigger: 'blur' }"
                                >
                                    <a-tree-select
                                        :fieldNames="{
                                            children: 'children',
                                            label: 'projectName',
                                            value: 'projectId',
                                            key: 'projectId'
                                        }"
                                        :showSearch="true"
                                        :placeholder="'请输入或选择'"
                                        :allowClear="true"
                                        :treeData="tgNoSt.projectList"
                                        v-model:value="tgNoSt.form.parentId"
                                        @change="getTemplatePeople"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="项目优先级"
                                    name="projectPriority"
                                    :rules="{ required: true, message: '请选择项目优先级', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="[
                                            { label: '最高', value: '最高' },
                                            { label: '高', value: '高' },
                                            { label: '中', value: '中' },
                                            { label: '低', value: '低' },
                                            { label: '最低', value: '最低' }
                                        ]"
                                        :showSearch="true"
                                        :placeholder="'请输入或选择'"
                                        :allowClear="true"
                                        v-model:value="tgNoSt.form.projectPriority"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item label="计划开始时间" name="startTime" :rules="factoryRule.startTime">
                                    <a-date-picker
                                        v-model:value="tgNoSt.form.startTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择计划开始时间'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="计划结束时间" name="endTime" :rules="factoryRule.endTime">
                                    <a-date-picker
                                        v-model:value="tgNoSt.form.endTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择计划结束时间'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">团队成员</div>
                        </div>
                        <div class="extent-role">
                            <a-row :gutter="24">
                                <a-col
                                    :span="12"
                                    v-for="(item, index) in tgNoSt.form.projectExtendsRoleList"
                                    :key="index"
                                >
                                    <a-form-item
                                        :label="item.role"
                                        :name="['projectExtendsRoleList', index, 'userList']"
                                        :rules="{
                                            required: item.mandatory,
                                            message: `请选择${item.role}`,
                                            trigger: 'blur'
                                        }"
                                        :labelCol="{ span: 24 }"
                                        :wrapperCol="{ span: 24 }"
                                    >
                                        <a-select
                                            :options="tgNoSt.peopleList"
                                            mode="multiple"
                                            :allowClear="true"
                                            :dropdownMatchSelectWidth="true"
                                            :showSearch="true"
                                            :filterOption="
                                                (input, option) => {
                                                    return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                }
                                            "
                                            :fieldNames="{
                                                label: 'name',
                                                value: 'name'
                                            }"
                                            :showArrow="true"
                                            v-model:value="tgNoSt.form.projectExtendsRoleList[index].userList"
                                        />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                        </div>
                        <div v-if="tgNoSt.isEdit">
                            <a-col :span="24">
                                <a-form-item
                                    label="变更原因"
                                    name="reasonsChange"
                                    :rules="{
                                        required: true,
                                        message: '请输入变更原因',
                                        trigger: 'blur'
                                    }"
                                >
                                    <a-textarea v-model:value="tgNoSt.form.reasonsChange" />
                                </a-form-item>
                            </a-col>
                        </div>
                    </div>
                </a-form>
            </a-modal>
            <!--          新建模板项目-->
            <!--          新建产品-->
            <a-modal
                :title="iterationState.title"
                v-model:visible="iterationState.visible"
                @ok="submitIterationProject"
                width="1000px"
                :body-style="{ maxHeight: '800px', overflowY: 'auto' }"
                @cancel="iterationCancel"
                ok-text="提交"
                :maskClosable="false"
                destroy-on-close
                centered
                :ok-button-props="{ loading: iterationState.okDisabled }"
            >
                <a-form :model="iterationState.form" ref="iterationRef">
                    <div class="iteration-form">
                        <div class="pj-title">
                            <div class="pj-title-son">产品基础信息</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="产品名称"
                                    name="projectName"
                                    :rules="[{ required: true, message: '请输入产品名称', trigger: 'blur' }]"
                                >
                                    <a-input
                                        v-model:value="iterationState.form.projectName"
                                        :placeholder="inputHolder"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="产品级别"
                                    name="level"
                                    :rules="{ required: true, message: '请选择产品级别', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="iterationState.levelList"
                                        :showSearch="true"
                                        :placeholder="'请选择'"
                                        :allowClear="true"
                                        v-model:value="iterationState.form.level"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item label="产品简称">
                                    <a-input maxlength="10" show-count v-model:value="iterationState.form.projectCode" />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">产品项目阶段</div>
                        </div>
                        <a-row style="margin-bottom: 16px">
                            <a-col :span="24">
                                <a-form-item
                                    name="stage"
                                    :rules="{ required: true, message: '请选择产品项目阶段', trigger: 'blur' }"
                                >
                                    <a-radio-group v-model:value="iterationState.form.stage" style="width: 100%">
                                        <a-row>
                                            <a-col
                                                v-for="(item, index) in iterationState.stageList"
                                                :key="index"
                                                :span="getSpan(index)"
                                            >
                                                <a-radio :value="item.value">{{ item.value }}</a-radio></a-col
                                            >
                                        </a-row>
                                    </a-radio-group>
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">产品成员</div>
                        </div>
                        <div class="extent-role">
                            <a-row :gutter="24">
                                <a-col
                                    :span="12"
                                    v-for="(item, index) in iterationState.form.projectExtendsRoleList"
                                    :key="index"
                                >
                                    <a-form-item
                                        :label="item.role"
                                        :name="['projectExtendsRoleList', index, 'userList']"
                                        :rules="{
                                            required: item.mandatory,
                                            message: `请选择${item.role}`,
                                            trigger: 'blur'
                                        }"
                                        :labelCol="{ span: 24 }"
                                        :wrapperCol="{ span: 24 }"
                                    >
                                        <a-select
                                            :options="iterationState.peopleList"
                                            mode="multiple"
                                            :allowClear="true"
                                            :dropdownMatchSelectWidth="true"
                                            :showSearch="true"
                                            :filterOption="
                                                (input, option) => {
                                                    return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                }
                                            "
                                            :fieldNames="{
                                                label: 'name',
                                                value: 'name'
                                            }"
                                            :showArrow="true"
                                            v-model:value="iterationState.form.projectExtendsRoleList[index].userList"
                                            @focus="getPlist"
                                        />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                        </div>
                        <!--                        <div v-if="iterationState.isEdit">-->
                        <!--                            <a-col :span="24">-->
                        <!--                                <a-form-item-->
                        <!--                                    label="变更原因"-->
                        <!--                                    name="reasonsChange"-->
                        <!--                                    :rules="{-->
                        <!--                                        required: true,-->
                        <!--                                        message: '请输入变更原因',-->
                        <!--                                        trigger: 'blur'-->
                        <!--                                    }"-->
                        <!--                                >-->
                        <!--                                    <a-textarea v-model:value="iterationState.form.reasonsChange" />-->
                        <!--                                </a-form-item>-->
                        <!--                            </a-col>-->
                        <!--                        </div>-->
                    </div>
                </a-form>
            </a-modal>
            <!--          新建产品-->
            <!-- begin vid_4yjzv1uwp4 自定义模板_he486ofo0e -->
            <div class="body">
                <div class="left-tree">
                    <div class="tree-title">
                        <div class="tree-title-font">产研项目列表</div>
                        <div
                            class="new-add-icon"
                            v-permission="'50001252_vid_mtgj1yuhll'"
                            title="新建"
                            @click="handleShowSelectProjectType"
                        ></div>
                    </div>
                    <div class="tree-search-div">
                        <a-input
                            v-model:value="state.treeSearchName"
                            placeholder="请输入"
                            allow-clear
                            @change="debounceGetProjectTreeData"
                        >
                            <template #suffix>
                                <a-tooltip title="">
                                    <search-outlined />
                                </a-tooltip>
                            </template>
                        </a-input>
                    </div>
                    <div class="tree-div">
                        <a-tree
                            v-model:checkedKeys="state.treeProps.checkedKeys"
                            v-model:selectedKeys="state.treeProps.selectedKeys"
                            v-model:expandedKeys="state.treeProps.expandedKeys"
                            :fieldNames="{
                                children: 'children',
                                title: 'projectName',
                                key: 'projectId'
                            }"
                            :selectedBackgroundColor="'#EBF1FF'"
                            :backgroundColor="'#F5F5F5'"
                            :show-line="true"
                            :show-icon="true"
                            :tree-data="state.projectTreeDate"
                            @select="handleTreeSelect"
                        >
                            <template #title="{ projectName, stage, nodeType }">
                                <div class="tree-name">
                                    <div class="tree-font">{{ projectName }}</div>
                                    <a-tooltip v-if="stage && nodeType === 'MENU'" :title="stage">
                                        <span :class="getStageIcon(stage)" class="stage-icon"></span>
                                    </a-tooltip>
                                </div>
                            </template>
                        </a-tree>
                    </div>
                </div>
                <div class="right-content">
                    <a-tabs
                        v-model:activeKey="state.activeKey"
                        class="tab-box"
                        @change="state.tabRefreshCount++"
                        :destroyInactiveTabPane="true"
                    >
                        <a-tab-pane v-for="tab in state.tabs" :key="tab.key" :tab="tab.label">
                            <component
                                :active-key="state.activeKey"
                                :refresh-count="state.tabRefreshCount"
                                :is="tab.component"
                                v-bind="tab.getProps(state.selected, state.selected.projectId)"
                                @getTreeData="handleGiveSelectKeys"
                                @copyProject="handleCopyProject"
                            />
                        </a-tab-pane>
                        <div class="tab-btn">
                            <a-space :size="16" v-if="state.selected && state.selected.nodeType === 'MENU'">
                                <a-button
                                    type="primary"
                                    size="small"
                                    @click="editIterationProject"
                                    ghost
                                    v-permission="'50001252_vid_0ltt3yyxii'"
                                    >编辑</a-button
                                >
                                <a-button
                                    type="primary"
                                    size="small"
                                    @click="handleShowDelete"
                                    ghost
                                    v-permission="'50001252_vid_ksvntbfoi1'"
                                    >删除</a-button
                                >
                            </a-space>
                            <a-space :size="16" v-if="state.selected && state.selected.nodeType === 'PROJECT'">
                                <a-button
                                    type="primary"
                                    size="small"
                                    @click="editTgNoProject"
                                    ghost
                                    v-permission="'50001252_vid_cpe64ul0ic'"
                                    >编辑</a-button
                                >
                                <a-button
                                    type="primary"
                                    size="small"
                                    @click="handleShowDelete"
                                    ghost
                                    v-permission="'50001252_vid_wx4ee85f3d'"
                                    >删除</a-button
                                >
                            </a-space>
                        </div>
                    </a-tabs>
                </div>
            </div>
            <!-- end vid_4yjzv1uwp4 自定义模板_he486ofo0e -->
        </a-spin>
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated,
        nextTick
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'
    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'
    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    function checkRequired(value, msg = '必填项缺失') {
        if (value === undefined || value === null || value === '') {
            message.warning(msg) // 这里用 Antd 的 message，也可以改成 console.error 或 throw Error
            return false
        }
        return true
    }
    const inputHolder = '请输入'
    const selectHolder = '请选择'
    onMounted(() => {
        getProjectTreeList()
        getStageList()
        getLevelList()
        state.tabs = parentTabs
        state.activeKey = parentTabs[0].key
    })
    const state = reactive({
        treeProps: {
            lazyParams: undefined,
            clickNode: { nodeTitle: '', nodeKey: '', nodeParentKey: '' },
            checkedKeys: [],
            selectedKeys: [],
            expandedKeys: [],
            treeData: []
        },
        treeSearchName: undefined,
        projectTreeDate: [],
        activeKey: '',
        deleteVisible: false,
        tabRefreshCount: 0,
        deleteLoading: false,
        projectSwitch: true,
        selected: {},
        selectProjectTypeVisible: false,
        selectProjectTypeRadioValue: '迭代产品'
    })
    // 获取字典
    function getStageList() {
        get('/solution-ppm-basic-data/api/v1/dictionary/search/CYXM.CPJD').then(data => {
            iterationState.stageList = data.data.map(item => {
                return {
                    label: item.itemName,
                    value: item.itemName
                }
            })
            iterationState.form.stage = iterationState.stageList[0].label
        })
    }
    function getLevelList() {
        get('/solution-ppm-basic-data/api/v1/dictionary/search/CYXM.CPJB').then(data => {
            iterationState.levelList = data.data.map(item => {
                return {
                    label: item.itemName,
                    value: item.itemName
                }
            })
        })
    }
    // 选择创建项目的类型
    function handleConfirmSelectType() {
        if (state.selectProjectTypeRadioValue === '迭代产品') {
            handleAddTgNoProject()
            state.selectProjectTypeRadioValue = '迭代产品'
        } else {
            handleAddIterationProject()
            state.selectProjectTypeRadioValue = '迭代产品'
        }
    }
    // 页面里直接手写防抖
    function debounce(fn, delay = 500) {
        let timer = null
        const debounced = function (...args) {
            clearTimeout(timer)
            timer = setTimeout(() => {
                fn.apply(this, args)
            }, delay)
        }
        debounced.cancel = () => {
            clearTimeout(timer)
            timer = null
        }
        return debounced
    }
    const debounceGetProjectTreeData = debounce(() => {
        getProjectTreeList()
    }, 500)
    // 额外存一个上一次选择的类型
    let prevType = null

    let handleTreeSelect = throttle(async (keys, e) => {
        if (!keys || keys.length === 0) {
            state.selected = null
            state.tabs = []
            state.activeKey = ''
            prevType = null
            return
        }

        const node = e?.selectedNodes?.[0]
        state.selected = node
        state.selected.projectId = keys[0]

        // 判断新类型
        let newTabs = []
        let newType = null
        if (node?.nodeType === 'MENU') {
            newTabs = parentTabs
            newType = 'MENU'
        } else if (node?.nodeType === 'PROJECT') {
            newTabs = childTabs
            newType = 'PROJECT'
        }

        state.tabs = newTabs

        if (prevType !== newType) {
            // 类型变了 → 强制回到第一个
            state.activeKey = newTabs.length > 0 ? newTabs[0].key : ''
        } else {
            // 类型没变 → 保持原来的
            const exist = newTabs.find(tab => tab.key === state.activeKey)
            state.activeKey = exist ? state.activeKey : newTabs.length > 0 ? newTabs[0].key : ''
        }

        prevType = newType
    }, 500)

    const projectId = ref()
    //     获取项目树
    async function getProjectTreeList() {
        await post('/solution-ppm/api/v2/built-in-system-ppm/v2/platform/project/tree', {
            projectName: state.treeSearchName
        }).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return false
            }
            state.projectTreeDate = processProjectTree(data.data)
            return true
        })
        await nextTick()
        if (route.query.projectId && route.query.tabKey) {
            navigateToProjectTab({
                projectId: Number(route.query.projectId),
                tabKey: route.query.tabKey
            })
        }
    }
    function processProjectTree(treeData) {
        return treeData.map(node => {
            // 如果是产品节点并且有子节点
            if (node.nodeType === 'MENU' && Array.isArray(node.children)) {
                // 按创建时间倒序排列
                const sortedChildren = [...node.children]

                // 如果超过 5 个，则截取前 5 个，其余放入“更多”
                if (sortedChildren.length > 5) {
                    const firstFive = sortedChildren.slice(0, 5)
                    const rest = sortedChildren.slice(5)

                    const moreNode = {
                        projectId: `${node.projectId}-more`,
                        projectName: '更多',
                        nodeType: 'MORE',
                        children: rest
                    }

                    node.children = [...firstFive, moreNode]
                } else {
                    node.children = sortedChildren
                }
            }

            // 递归处理下级节点（如果存在）
            if (node.children && node.children.length) {
                node.children = processProjectTree(node.children)
            }

            return node
        })
    }

    // 项目详情
    const getProjectDetail = async () => {
        const url = `/solution-ppm/api/v2/built-in-system-ppm/platform_product/product_project/${state.selected.projectId}`
        return await get(url)
            .then(async resp => {
                return resp.data
            })
            .catch(async e => {
                return Promise.reject(e)
            })
            .finally(async () => {})
    }
    // 新建选择类型
    function handleShowSelectProjectType() {
        state.selectProjectTypeVisible = true
    }
    // 复制项目
    function handleCopyProject() {
        // 使用 Promise.all() 等待所有异步方法完成
        Promise.all([getFactory(), getPlist(), getProjectList(), getTemplate()])
            .then(async () => {
                // 在所有方法都成功完成后执行最后一步
                let projectDetail = await getProjectDetail()
                tgNoSt.form = Object.assign({}, tgNoSt.form, projectDetail)
                tgNoSt.form.projectName = tgNoSt.form.startTime = tgNoSt.form.endTime = undefined
                getTemplatePeople()
                tgNoSt.visible = true
                tgNoSt.isEdit = false
                tgNoSt.isCopy = true
                tgNoSt.title = '复制模板项目'
                delete tgNoSt.form.createTime
                delete tgNoSt.form.updateTime
            })
            .catch(error => {
                // 如果其中任何一个方法失败，处理错误
                console.error('Error:', error)
            })
    }
    // 模板平台项目=======================================================================
    //     新建项目

    const tgNoSt = reactive({
        visible: false,
        isEdit: false,
        isCopy: false,
        title: '',
        okDisabled: false,
        form: {
            projectTemplate: undefined,
            projectName: undefined,
            parentId: undefined,
            projectPriority: '中',
            startTime: undefined,
            endTime: undefined,
            projectExtendsRoleList: []
        },

        projectTemplateList: [],
        //   工厂列表
        factoryNameList: [],
        //   项目关联菜单
        projectList: [],
        //   人列表
        peopleList: []
    })
    // 获取模板列表
    function getTemplate() {
        get('/solution-ppm/api/v2/built-in-system-ppm/project/template/create/platform_template_list').then(data => {
            if (data.code === 200) {
                tgNoSt.projectTemplateList = data.data.dataList
            } else {
                message.error('获取模板失败！')
            }
        })
    }

    //     获取工厂
    function getFactory() {
        get('/solution-ppm/api/v2/built-in-system-ppm/project_template/ptf/search').then(data => {
            if (data.code === 200) {
                tgNoSt.factoryNameList = data.data
            } else {
                message.error('获取工厂名称失败！')
            }
        })
    }

    const factoryRule = {
        factory: [
            {
                required: true,
                trigger: 'blur',
                validator: async (rule, value, callback) => {
                    if (!value) {
                        return Promise.reject('请选择工厂名称')
                    }
                    const { data } = await post(
                        `/solution-ppm/api/v2/built-in-system-ppm/project_template/check_factory_valid/${value}`
                    )

                    return data ? Promise.resolve() : Promise.reject(new Error('请选择区域下的工厂'))
                }
            }
        ],
        startTime: [
            {
                required: true,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    if (!value) {
                        return Promise.reject('请输入项目开始时间')
                    }
                    if (
                        value &&
                        tgNoSt.form.endTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >
                            dayjs(tgNoSt.form.endTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('计划开始时间不能晚于计划结束时间')
                    }
                    return Promise.resolve()
                }
            }
        ],
        endTime: [
            {
                required: true,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    if (
                        value &&
                        tgNoSt.form.startTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <
                            dayjs(tgNoSt.form.startTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('计划结束时间不能早于计划开始时间')
                    }
                    return Promise.resolve()
                }
            }
        ]
    }

    function getProjectList() {
        post('/solution-ppm/api/v2/built-in-system-ppm/v2/platform/project/tree', {
            source: 'MENU',
            nodeType: 'MENU'
        }).then(data => {
            if (data.code === 200) {
                tgNoSt.projectList = data.data
            } else {
                message.error('获取菜单失败！')
            }
        })
    }

    function getPlist() {
        get('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/allUser').then(data => {
            if (data.code === 200) {
                tgNoSt.peopleList = data.data.userDtoList
                iterationState.peopleList = data.data.userDtoList
            } else {
                message.error('获取用户列表失败！')
            }
        })
    }

    function handleAddTgNoProject() {
        getPlist()
        getProjectList()
        tgNoSt.visible = true
        tgNoSt.title = '新建迭代产品'
        tgNoSt.isEdit = false
        tgNoSt.isCopy = false
    }

    const tgNoStRef = ref(null)

    function getTemplatePeople() {
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/platform_product/product_extends_role/${tgNoSt.form.parentId}`
        ).then(data => {
            if (data.code !== 200) {
                tgNoSt.form.projectExtendsRoleList = []
                return
            }
            tgNoSt.form.projectExtendsRoleList = data.data
        })
    }
    function submitTgNoProject() {
        tgNoStRef.value
            .validate()
            .then(() => {
                tgNoSt.okDisabled = true
                const params = cloneDeep(tgNoSt.form)
                params.projectExtendsRoleList.forEach(item => {
                    item.user = item.userList.join(',')
                })
                if (tgNoSt.isEdit) {
                    post('/solution-ppm/api/v2/built-in-system-ppm/v2/platform_project_template/edit', params)
                        .then(data => {
                            if (data.code === 200) {
                                message.success('编辑项目已进入审批流程')
                                tgNoSt.visible = false
                                // TODO调树
                                resetTgPjForm()
                            } else {
                                message.error(data.message)
                            }
                        })
                        .finally(() => {
                            tgNoSt.okDisabled = false
                        })
                } else {
                    // 新增推广有模板项目
                    post('/solution-ppm/api/v2/built-in-system-ppm/v2/platform_project_template/add', params)
                        .then(data => {
                            if (data.code === 200) {
                                message.success('新建项目已进入审批流程')
                                // TODO调树
                                tgNoSt.visible = false
                                resetTgPjForm()
                                getProjectTreeList()
                                state.selectProjectTypeVisible = false
                              state.tabRefreshCount++
                            } else {
                                message.error(data.message)
                            }
                        })
                        .finally(() => {
                            tgNoSt.okDisabled = false
                        })
                }
            })
            .catch(() => {
                //校验未通过执行这里
                const errorList = document.querySelectorAll('.ant3-form-item-has-error')
                errorList[0]?.scrollIntoView({
                    block: 'center',
                    behavior: 'smooth'
                })
            })
    }

    function editTgNoProject() {
        if (!checkRequired(state.selected.projectId, '请选择产品')) return
        // 使用 Promise.all() 等待所有异步方法完成
        Promise.all([getFactory(), getPlist(), getProjectList(), getTemplate()])
            .then(async () => {
                // 在所有方法都成功完成后执行最后一步
                let projectDetail = await getProjectDetail()
                tgNoSt.form = Object.assign({}, tgNoSt.form, projectDetail)
                tgNoSt.visible = true
                tgNoSt.isEdit = true
                tgNoSt.isCopy = false
                tgNoSt.title = '编辑模板项目'
                delete tgNoSt.form.createTime
                delete tgNoSt.form.updateTime
            })
            .catch(error => {
                // 如果其中任何一个方法失败，处理错误
                console.error('Error:', error)
            })
    }

    function tgNoStCancel() {
        resetTgPjForm()
        tgNoSt.visible = false
    }

    function resetTgPjForm() {
        tgNoSt.form = {
            projectTemplate: undefined,
            projectName: undefined,
            parentId: undefined,
            projectPriority: '中',
            startTime: undefined,
            endTime: undefined,
            projectExtendsRoleList: []
        }
    }

    // 模板平台项目=======================================================================
    // 迭代产品新建========================================================================
    const iterationState = reactive({
        visible: false,
        isEdit: false,
        isCopy: false,
        title: '',
        okDisabled: false,
        form: {
            projectName: undefined,
            level: undefined,
            projectCode: undefined,
            stage: undefined,
            projectExtendsRoleList: []
        },

        projectTemplateList: [],
        //   工厂列表
        factoryNameList: [],
        //   项目关联菜单
        projectList: [],
        //   人列表
        peopleList: [],
        levelList: [],
        stageList: []
    })
    function handleAddIterationProject() {
        getIterationProjectExtendRoleList()
        iterationState.visible = true
        iterationState.title = '新建产品'
        iterationState.isEdit = false
        iterationState.isCopy = false
    }
    function getIterationProjectExtendRoleList() {
        get('/solution-ppm/api/v2/built-in-system-ppm/platform_product/role').then(data => {
            iterationState.form.projectExtendsRoleList = data.data
        })
    }
    const iterationRef = ref(null)

    function submitIterationProject() {
        iterationRef.value
            .validate()
            .then(() => {
                iterationState.okDisabled = true
                const params = cloneDeep(iterationState.form)
                params.projectExtendsRoleList.forEach(item => {
                    item.user = item.userList.join(',')
                })
                if (iterationState.isEdit) {
                    put('/solution-ppm/api/v2/built-in-system-ppm/platform_product', params)
                        .then(data => {
                            if (data.code === 200) {
                                iterationState.visible = false
                                // TODO调树
                                state.selectProjectTypeVisible = false
                                message.success(data.message)
                                resetIterationForm()
                                getProjectTreeList()
                              state.tabRefreshCount++
                            } else {
                                message.error(data.message)
                            }
                        })
                        .finally(() => {
                            iterationState.okDisabled = false
                        })
                } else {
                    // 新增推广有模板项目
                    post('/solution-ppm/api/v2/built-in-system-ppm/platform_product', params)
                        .then(data => {
                            if (data.code === 200) {
                                // TODO调树
                                iterationState.visible = false
                                message.success(data.message)
                                resetIterationForm()
                                getProjectTreeList()
                                state.selectProjectTypeVisible = false
                            } else {
                                message.error(data.message)
                            }
                        })
                        .finally(() => {
                            iterationState.okDisabled = false
                        })
                }
            })
            .catch(() => {
                //校验未通过执行这里
                const errorList = document.querySelectorAll('.ant3-form-item-has-error')
                errorList[0]?.scrollIntoView({
                    block: 'center',
                    behavior: 'smooth'
                })
            })
    }

    async function editIterationProject() {
        if (!checkRequired(state.selected.projectId, '请选择产品')) return
        let projectDetail = await getProjectDetail()
        iterationState.form = Object.assign({}, iterationState.form, projectDetail)
        iterationState.visible = true
        iterationState.isEdit = true
        iterationState.isCopy = false
        iterationState.title = '编辑模板项目'
        delete iterationState.form.createTime
        delete iterationState.form.updateTime
    }

    function iterationCancel() {
        resetIterationForm()
        iterationState.visible = false
    }

    function resetIterationForm() {
        iterationState.form = {
            projectName: undefined,
            level: undefined,
            projectCode: undefined,
            stage: undefined,
            projectExtendsRoleList: []
        }
    }

    // 迭代产品新建=============================================================================
    //     动态展示tab
    // 父节点对应的 tab 列表
    // 目标
    import Target from './Page3000001092.vue'
    // 用户故事&任务
    import StoryAndTask from './Page3000001150.vue'
    // 版本管理
    import Version from './Page3000001154.vue'
    // 资源管理
    import Resource from './Page3000001185.vue'
    // 文件管理
    import FileManagement from './Page3000001186.vue'
    // 需求管理
    import RequirementsManagement from './Page3000001226.vue'
    // 风险
    import Risk from './Page3000001188.vue'
    // 变更记录一级
    import Changelog from './Page3000001187.vue'
    // 项目概览一级
    import OverviewOne from './Page3000001189.vue'
    // 项目概览二级
    import OverviewSecond from './Page3000001190.vue'

    // 父节点（MENU）tabs 配置
    const parentTabs = [
        {
            key: 'overview',
            label: '项目概览',
            component: OverviewOne,
            getProps: (node, pid) => ({ useProjectId: pid })
        },
        { key: 'target', label: '目标', component: Target, getProps: (node, pid) => ({ id: pid }) },
        { key: 'version', label: '版本管理', component: Version, getProps: (node, pid) => ({ projectId: pid }) },
        { key: 'resource', label: '资源管理', component: Resource, getProps: (node, pid) => ({ useProjectId: pid }) },
        {
            key: 'fileManagement',
            label: '文件管理',
            component: FileManagement,
            getProps: (node, pid) => ({ useProjectId: pid })
        },
        {
            key: 'RequirementsManagement',
            label: '需求管理',
            component: RequirementsManagement,
            getProps: (node, pid) => ({ useProjectId: pid })
        }
    ]

    // 子节点（PROJECT）tabs 配置
    const childTabs = [
        {
            key: 'overviewSecond',
            label: '项目概览',
            component: OverviewSecond,
            getProps: (node, pid) => ({ useProjectId: pid })
        },
        {
            key: 'storyAndTask',
            label: '用户故事&任务',
            component: StoryAndTask,
            getProps: (node, pid) => ({
                projectId: pid,
                iterationVersionId: route.query.iterationVersionId,
                storyId: route.query.storyId
            })
        },
        {
            key: 'risk',
            label: '风险',
            component: Risk,
            getProps: (node, pid) => ({ useProjectId: pid })
        },
        {
            key: 'Changelog',
            label: '变更记录',
            component: Changelog,
            getProps: (node, pid) => ({ useProjectId: pid })
        }
    ]

    //     动态展示tab
    //     删除项目
    function handleShowDelete() {
        if (!checkRequired(state.selected.projectId, '请选择产品')) return
        state.deleteVisible = true
    }

    function handleSubmitDelete() {
        state.deleteLoading = true
        if (state.selected.nodeType === 'MENU') {
            del(`/solution-ppm/api/v2/built-in-system-ppm/platform_product/${state.selected.projectId}`)
                .then(data => {
                    if (data.code !== 200) {
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    getProjectTreeList()
                })
                .finally(() => {
                    state.deleteLoading = false
                })
        } else {
            del(`/solution-ppm/api/v2/built-in-system-ppm/v2/platform/project/${state.selected.projectId}`)
                .then(data => {
                    if (data.code !== 200) {
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    getProjectTreeList()
                })
                .finally(() => {
                    state.deleteLoading = false
                })
        }
    }
    async function handleGiveSelectKeys(data) {
        await getProjectTreeList()
        state.treeProps.selectedKeys = [data.id]
    }
    // setup 里定义一个方法
    const getStageIcon = stageName => {
        switch (stageName) {
            case '研究阶段立项':
                return 'yjjdlx'
            case '研究阶段':
                return 'yjjd'
            case '开发阶段立项':
                return 'kfjdlx'
            case '开发阶段':
                return 'kfjd'
            case '结项阶段':
                return 'jxjd'
            case '上市阶段':
                return 'ssjd'
            case '效益复盘':
                return 'xyfp'
            default:
                return ''
        }
    }
    function getSpan(index) {
        if (index === 0 || index === 2) {
            return 4
        } else {
            return 3
        }
    }
    //     跳转新需求
    function navigateToProjectTab({ projectId, tabKey }) {
        const targetNode = findNodeByKey(state.projectTreeDate, projectId)
        // 🚫 如果没找到（可能因为无权限或项目被删除）
        if (!targetNode) {
            message.warning('当前用户无权访问该项目或项目已不存在')
            return
        }

        // 找到目标节点的所有父级 key
        const parentKeys = findParentKeys(state.projectTreeDate, projectId)

        // ✅ 更新展开与选中
        state.treeProps.expandedKeys = [...new Set([...state.treeProps.expandedKeys, ...parentKeys, projectId])]
        state.treeProps.selectedKeys = [projectId]

        // ✅ 模拟 @select 事件
        handleTreeSelect([projectId], { selectedNodes: [targetNode] })
        state.activeKey = tabKey
    }
    // ✅ 递归查找指定节点的所有父级 key
    function findParentKeys(list, key, path = []) {
        for (const item of list) {
            if (item.projectId === key) return path
            if (item.children?.length) {
                const result = findParentKeys(item.children, key, [...path, item.projectId])
                if (result.length) return result
            }
        }
        return []
    }
    // ✅ 查找指定 key 的节点
    function findNodeByKey(list, key) {
        for (const item of list) {
            if (item.projectId === key) return item
            if (item.children?.length) {
                const found = findNodeByKey(item.children, key)
                if (found) return found
            }
        }
        return null
    }
    console.log(route.query, 'route.query')
    import { nextTick } from 'vue'
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }
    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }
    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }
    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }
    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }
    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }
    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }
    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }
    /*样式*/

    .body {
        display: flex;
        gap: 16px;
        height: 100%;
    }
    /*左侧树*/
    .left-tree {
        width: 16%;
        display: flex;
        flex-direction: column;
        background-color: #fff;
    }

    .svg-icon {
        display: none;
        position: relative;
        top: 3px;
        outline: none;
    }
    .tree-btns {
        display: flex;
        justify-content: space-around;
    }
    :deep(.ant3-tree-node-content-wrapper:hover) .svg-icon {
        display: inline-block;
    }
    .new-add-icon {
        width: 16px;
        height: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/492790240417114112-source.png');
        background-size: cover;
        cursor: pointer;
        margin-bottom: 3px;
    }
    .tree-title {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 16px 24px 0;
    }
    .tree-title-font {
        font-weight: 600;
        color: #262626;
    }
    .tree-search-div {
        margin-top: 8px;
        margin-bottom: 16px;
        padding-right: 24px;
        padding-left: 24px;
    }
    .tree-div {
        flex: 1;
        padding: 0 24px;
        overflow-y: auto;
    }
    /*左侧树*/
    /*右侧内容*/
    .right-content {
        flex: 1;
        padding-right: 16px;
        padding-bottom: 16px;
        padding-left: 16px;
        background-color: #fff;
        overflow: hidden;
    }
    .tab-btn {
        position: absolute;
        right: 0;
        top: 12px;
    }
    .tab-box {
        position: relative;
    }
    /*右侧内容*/

    /*模板项目样式*/
    /*
        定制
        */
    .pj-title {
        height: 30px;
        border-bottom: 1px solid #bfbfbf;
        margin-bottom: 16px;
    }

    .pj-title-son {
        font-size: 14px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        border-left: 4px solid #3875ff;
        padding-left: 5px;
        height: 18px;
        line-height: 18px;
    }

    :deep(.tg-no-st .ant3-form-item-label) {
        width: 115px !important;
    }
    :deep(.iteration-form .ant3-form-item-label) {
        width: 85px !important;
    }

    .del {
        width: 66px;
        color: #3875ff;
        float: right;
    }

    .add-btn-role {
        margin-bottom: 20px;
    }

    .role-content {
        display: inline-block;
        width: calc(100% - 80px);
    }

    :deep(.role-content .ant3-form-item-label) {
        width: 115px !important;
    }

    .no-border {
        border: none;
    }
    .table-box :deep(.@{ant-prefix}-table-tbody) tr > td {
        font-size: 14px;
        font-weight: 400;
        color: #262626;
        border-bottom: 1px solid #d9d9d9;
        padding: 8px 16px;
        word-break: break-all;
    }
    /*模板项目样式*/
    .yjjdlx,
    .yjjd,
    .kfjdlx,
    .kfjd,
    .jxjd,
    .ssjd,
    .xyfp {
        width: 16px;
        height: 16px;
        background-size: cover;
        flex-shrink: 0;
    }
    .yjjdlx {
        background-image: url('http://10.40.0.33:9001/file-storage/531434247375108096-source.png');
    }
    .yjjd {
        background-image: url('http://10.40.0.33:9001/file-storage/531434220309264384-source.png');
    }
    .kfjdlx {
        background-image: url('http://10.40.0.33:9001/file-storage/531434101583198208-source.png');
    }
    .kfjd {
        background-image: url('http://10.40.0.33:9001/file-storage/531434061735213056-source.png');
    }
    .jxjd {
        background-image: url('http://10.40.0.33:9001/file-storage/531434030753986560-source.png');
    }
    .ssjd {
        background-image: url('http://10.40.0.33:9001/file-storage/531434149779945472-source.png');
    }
    .xyfp {
        background-image: url('http://10.40.0.33:9001/file-storage/531434188644366336-source.png');
    }
    .tree-name {
        display: flex;
        align-items: center;
        gap: 4px;
    }

    .stage-icon {
        width: 16px;
        height: 16px;
        background-size: cover;
    }

    /*
        定制
        */
</style>
